Sei specific MCP - #13
Conversation
WalkthroughThis update transitions the project from a multi-chain EVM server to a Sei-only MCP server. All code, documentation, configuration, and tools are refactored to exclusively support the Sei blockchain (mainnet, testnet, devnet). ENS and multi-chain logic are removed, private key management is centralized via environment variables, and comprehensive tests are introduced. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant MCPServer
participant Config
participant Services
User->>MCPServer: Request (e.g., transfer_sei)
MCPServer->>Config: Get PRIVATE_KEY
Config-->>MCPServer: Formatted private key (with 0x)
MCPServer->>Services: Validate addresses, execute transfer
Services-->>MCPServer: Transaction result
MCPServer-->>User: Response (tx hash or error)
Poem
Note ⚡️ AI Code Reviews for VS Code, Cursor, WindsurfCodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback. Note ⚡️ Faster reviews with cachingCodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure ✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 7
🔭 Outside diff range comments (2)
README.md (2)
199-205: 🛠️ Refactor suggestionUpdate server name in mcp.json example
The mcp.json example still uses the old server name which is inconsistent with the rebranding.
{ "mcpServers": { - "evm-mcp-server": { + "sei-mcp-server": { "command": "npx", "args": [ "-y", "@sei-protocol/sei-mcp-server"
232-234: 🛠️ Refactor suggestionUpdate server name in HTTP mode example
Update the SSE example server name to match the rebranding.
{ "mcpServers": { - "evm-mcp-sse": { + "sei-mcp-sse": { "url": "http://localhost:3001/sse"
🧹 Nitpick comments (13)
.env.example (1)
1-6: Good implementation of environment variable template.The
.env.examplefile provides clear documentation for the PRIVATE_KEY variable with appropriate security warnings. Consider adding guidance on what type of key should be used (e.g., dedicated service account with minimal funds).# Sei MCP Server Environment Variables # Private key for blockchain transactions (without 0x prefix) # This is used when no private key is provided in the request # SECURITY: Never commit your actual private key to version control +# RECOMMENDATION: Use a dedicated key with minimal funds for security PRIVATE_KEY=your_private_key_heresrc/core/resources.ts (1)
217-249: Default balance resource uses appropriate naming.Consider renaming the
default_sei_balanceresource identifier to be more consistent, as the URL template still contains "eth-balance". This minor inconsistency between the resource name and its URL pattern could cause confusion.- "default_sei_balance", + "default_native_balance", new ResourceTemplate("evm://address/{address}/eth-balance", { list: undefined }),You might also want to update the URL template to use "sei-balance" or "native-balance" for complete consistency.
src/core/services/clients.ts (1)
57-65: Consider integrating with centralized private key management.The
getAddressFromPrivateKeyfunction still requires a private key parameter while other parts of the codebase now use the centralized config for private key management.Consider adding an overload that can use the private key from the environment:
/** * Get an EVM address from a private key * * @param privateKey The private key in hex format (with or without 0x prefix) * @returns The EVM address derived from the private key */ export function getAddressFromPrivateKey(privateKey: Hex): Address { const account = privateKeyToAccount(privateKey); return account.address; } + +/** + * Get an EVM address from the environment variable private key + * + * @returns The EVM address derived from the environment variable private key or undefined if not set + */ +export function getAddressFromEnvPrivateKey(): Address | undefined { + const privateKey = getPrivateKeyAsHex(); + if (!privateKey) return undefined; + return getAddressFromPrivateKey(privateKey); +}You would need to import
getPrivateKeyAsHexfrom the config module.src/tests/core/config.test.ts (2)
11-11: Minor performance improvement opportunity.The static analysis tool suggests avoiding the
deleteoperator for performance reasons.- delete process.env.PRIVATE_KEY; + process.env.PRIVATE_KEY = undefined;However, the performance impact is negligible in test code.
🧰 Tools
🪛 Biome (1.9.4)
[error] 11-11: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
19-51: Tests are tightly coupled to implementation details.The tests directly modify
config.privateKeywith@ts-ignoreto bypass type checking, which makes them fragile to implementation changes.Consider refactoring the tests to be less dependent on implementation details:
- Export the formatting function from the config module for direct testing
- Or create a test utility that reloads the module with different environment variables
The current approach works but might be difficult to maintain if the implementation changes.
src/tests/core/services/tools.test.ts (1)
5-10: MockServer implementation could use better typing.The
Functiontype is being used as a generic type, which isn't recommended.Consider using a more specific function type:
- tools: { name: string; description: string; schema: any; handler: Function }[] = []; - tool(name: string, description: string, schema: any, handler: Function) { + tools: { name: string; description: string; schema: any; handler: (...args: any[]) => any }[] = []; + tool(name: string, description: string, schema: any, handler: (...args: any[]) => any) {🧰 Tools
🪛 Biome (1.9.4)
[error] 6-6: Don't use 'Function' as a type.
Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.
(lint/complexity/noBannedTypes)
[error] 7-7: Don't use 'Function' as a type.
Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.
(lint/complexity/noBannedTypes)
README.md (3)
125-135: Consider clarifying PRIVATE_KEY usage in documentationThe environment variable section clearly explains the private key usage but could use a slight wording enhancement to clarify the implementation.
- `PRIVATE_KEY`: **Required** private key for any blockchain operations that involve signing transactions (e.g., transferring tokens, interacting with smart contracts that modify state). This is the **sole method** for providing a private key. If this environment variable is not set when a transaction-signing tool is invoked, the tool will return an error message instructing the AI assistant to ask the user to set the `PRIVATE_KEY` environment variable and restart the MCP server. + `PRIVATE_KEY`: **Required** for any blockchain operations that involve signing transactions (e.g., transferring tokens, interacting with smart contracts that modify state). This is the **sole method** for providing a private key. If this environment variable is not set when a transaction-signing tool is invoked, the tool will return an error message instructing the AI assistant to ask the user to set the `PRIVATE_KEY` environment variable and restart the MCP server.🧰 Tools
🪛 LanguageTool
[uncategorized] ~125-~125: Loose punctuation mark.
Context: ... environment variables: -PRIVATE_KEY: Required private key for any blockc...(UNLIKELY_OPENING_PUNCTUATION)
310-311: Use clearer example addressesThe example uses what appear to be real addresses. Consider using addresses clearly labeled as examples.
const result = await mcp.invokeTool("get-token-balance", { - tokenAddress: "0x3894085ef7ff0f0aedf52e2a2704928d1ec074f1", // USDC on Sei - ownerAddress: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", + tokenAddress: "0x1234...5678", // Example USDC on Sei + ownerAddress: "0xabcd...ef01", // Example wallet address🧰 Tools
🪛 Gitleaks (8.26.0)
310-310: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
317-318: Update example output addressesFor consistency, update the example output addresses to match the input examples.
// { -// tokenAddress: "0x3894085ef7ff0f0aedf52e2a2704928d1ec074f1", -// owner: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", +// tokenAddress: "0x1234...5678", +// owner: "0xabcd...ef01",🧰 Tools
🪛 Gitleaks (8.26.0)
317-317: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
src/core/services/balance.ts (1)
74-87: Renameetheroutput to avoid Ethereum-specific terminologyThe function targets the Sei network, yet still returns the formatted balance under the property name
ether.
Consider renaming this key to something neutral (formatted) or Sei-specific (sei) to prevent confusion for downstream callers and future readers.-return { - wei: balance, - ether: formatEther(balance) -}; +return { + wei: balance, + formatted: formatEther(balance) // or `sei` +};src/core/tools.ts (3)
148-151: Remove residual ENS references from parameter descriptionsThe project no longer supports ENS resolution, yet the description still suggests ENS names (
'vitalik.eth').
Update the text to avoid misleading users.- address: z.string().describe("The wallet address name (e.g., '0x1234...' or 'vitalik.eth') to check the balance for"), + address: z.string().describe("The wallet address (e.g., '0x1234...') to check the balance for"),
371-380: Tool description still mentions ENS for transfers
transfer_seimentions ENS in both the parameter description and example, which is no longer valid.Search & replace ENS mentions in all tool descriptions to keep docs consistent with actual capabilities.
910-914: Update NFT-ownership tool docs to drop ENS examples
check_nft_ownershipstill references.ethnames fortokenAddressandownerAddress.
Replace with plain hex-address examples to match the new validate-only workflow.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (25)
.cursor/mcp.json(0 hunks).env.example(1 hunks).gitignore(1 hunks)README.md(11 hunks)package.json(5 hunks)src/core/chains.ts(5 hunks)src/core/config.ts(1 hunks)src/core/prompts.ts(8 hunks)src/core/resources.ts(22 hunks)src/core/services/balance.ts(6 hunks)src/core/services/blocks.ts(5 hunks)src/core/services/clients.ts(3 hunks)src/core/services/contracts.ts(1 hunks)src/core/services/ens.ts(0 hunks)src/core/services/index.ts(1 hunks)src/core/services/tokens.ts(5 hunks)src/core/services/transactions.ts(3 hunks)src/core/services/transfer.ts(10 hunks)src/core/services/utils.ts(1 hunks)src/core/tools.ts(31 hunks)src/tests/core/config.test.ts(1 hunks)src/tests/core/services/balance.test.ts(1 hunks)src/tests/core/services/tools.test.ts(1 hunks)src/tests/core/services/transfer.test.ts(1 hunks)src/tests/core/services/utils.test.ts(1 hunks)
💤 Files with no reviewable changes (2)
- .cursor/mcp.json
- src/core/services/ens.ts
🧰 Additional context used
🧬 Code Graph Analysis (8)
src/core/services/transactions.ts (2)
src/core/services/index.ts (3)
Hash(14-14)TransactionReceipt(17-17)Address(13-13)src/core/services/clients.ts (1)
getPublicClient(19-40)
src/core/services/blocks.ts (1)
src/core/services/clients.ts (1)
getPublicClient(19-40)
src/tests/core/services/tools.test.ts (1)
src/core/tools.ts (1)
registerEVMTools(13-1111)
src/tests/core/services/balance.test.ts (1)
src/core/services/balance.ts (5)
getBalance(74-87)getERC20Balance(96-133)isNFTOwner(143-165)getERC721Balance(174-188)getERC1155Balance(198-213)
src/core/services/contracts.ts (3)
src/core/services/clients.ts (2)
getPublicClient(19-40)getWalletClient(45-55)src/core/services/index.ts (2)
Hash(14-14)Log(18-18)src/core/config.ts (1)
getPrivateKeyAsHex(34-36)
src/core/services/clients.ts (2)
src/core/chains.ts (2)
getChain(67-81)getRpcUrl(88-94)src/core/services/index.ts (2)
Hex(15-15)Address(13-13)
src/core/services/transfer.ts (3)
src/core/services/index.ts (2)
Hash(14-14)Address(13-13)src/core/config.ts (1)
getPrivateKeyAsHex(34-36)src/core/services/clients.ts (2)
getWalletClient(45-55)getPublicClient(19-40)
src/core/services/balance.ts (3)
src/core/services/clients.ts (1)
getPublicClient(19-40)src/core/services/contracts.ts (1)
readContract(15-18)src/core/services/index.ts (1)
Address(13-13)
🪛 Biome (1.9.4)
src/tests/core/config.test.ts
[error] 11-11: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
src/tests/core/services/tools.test.ts
[error] 6-6: Don't use 'Function' as a type.
Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.
(lint/complexity/noBannedTypes)
[error] 7-7: Don't use 'Function' as a type.
Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.
(lint/complexity/noBannedTypes)
src/core/chains.ts
[error] 16-16: Number literal with underscore is not allowed here.
Safe fix: Replace 713_715 with 713715
(lint/complexity/useSimpleNumberKeys)
[error] 30-30: Number literal with underscore is not allowed here.
Safe fix: Replace 713_715 with 713715
(lint/complexity/useSimpleNumberKeys)
🪛 LanguageTool
README.md
[uncategorized] ~31-~31: Possible missing comma found.
Context: ...AI agents. It supports a wide range of services including: - Reading blockchain state ...
(AI_HYDRA_LEO_MISSING_COMMA)
[uncategorized] ~125-~125: Loose punctuation mark.
Context: ... environment variables: - PRIVATE_KEY: Required private key for any blockc...
(UNLIKELY_OPENING_PUNCTUATION)
🪛 Gitleaks (8.26.0)
README.md
310-310: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
317-317: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (73)
.gitignore (1)
30-31: Good addition of environment variable handling.Adding
.envto .gitignore is a security best practice that aligns with the PR objective of improving private key management.src/core/services/index.ts (1)
12-19: Clean up of exports aligns with Sei-specific focus.The export structure has been reformatted while removing ENS-related functionality, which is consistent with the PR objective of making the server Sei-specific and removing non-working code.
package.json (4)
2-9: Rebranding to Sei-specific package is consistent.The package name, version reset to 1.0.0, and binary name updates all properly reflect the transition to a Sei-specific implementation.
25-25: Good addition of test script.Adding the test script aligns with the PR objective of introducing basic unit tests to the codebase.
45-45: Appropriate addition of dotenv dependency.Adding the dotenv package supports the goal of improving private key handling via environment variables.
55-55: Updated keywords reflect new focus.Replacing "ethereum" with "sei" in the keywords list properly reflects the project's new focus.
src/core/config.ts (3)
1-36: Well-structured centralized config implementation.This is a clean implementation of centralized private key management via environment variables. The use of zod for schema validation and proper typing with viem's Hex type is a good approach.
16-22: Good private key formatting logic.The private key formatting function correctly handles the 0x prefix, ensuring consistency in how private keys are stored and used throughout the application.
29-36: Well-documented utility function.The
getPrivateKeyAsHexfunction has clear documentation and proper return type annotation, making it easy for other modules to use this centralized key management.src/core/resources.ts (5)
43-55: Resource documentation updated to Sei.The comments and resource names have been appropriately updated to reflect the shift from Ethereum to Sei mainnet.
157-180: Default latest block resource properly configured for Sei.The default latest block resource has been correctly updated to use "sei" as the network, aligning with the project's focus on Sei blockchain.
183-216: Balance-related resources correctly adapted for Sei.The balance retrieval has been properly updated to use
services.getBalanceinstead ofservices.getETHBalanceand error messages now correctly reference "Sei balance".
293-333: Default ERC20 balance resource properly configured for Sei.The default ERC20 balance resource has been correctly updated to use "sei" as the network.
362-387: Default transaction resource properly configured for Sei.The default transaction resource has been correctly updated to use "sei" as the network.
src/core/services/clients.ts (3)
19-40: Default network properly updated to 'sei'.The
getPublicClientfunction has been correctly updated to use 'sei' as the default network parameter.
45-55: Default network properly updated in wallet client.The
getWalletClientfunction has been correctly updated to use 'sei' as the default network parameter.
57-65: Updated JSDoc to use more accurate terminology.The JSDoc comment has been appropriately updated to use the more general term "EVM" instead of "Ethereum" to reflect that the address is EVM-compatible.
src/tests/core/config.test.ts (2)
4-18: Good test setup and teardown.The use of
beforeEachandafterEachto manage environment variables is a good practice for isolated tests.🧰 Tools
🪛 Biome (1.9.4)
[error] 11-11: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
53-71: Good coverage of the getPrivateKeyAsHex function.The tests properly verify both the undefined case and the case where a private key is set.
src/tests/core/services/utils.test.ts (4)
1-3: Clean and proper imports.The imports are appropriate for Bun testing framework, pulling in necessary test utilities and the utils module being tested.
5-19: Tests for parseEther function look good.Comprehensive test cases covering typical values, fractional values, and the zero case. The tests properly verify BigInt conversion from string representations of Ether to Wei values.
21-62: Thorough formatJson testing.The tests properly verify:
- BigInt conversion to strings in JSON output
- Preservation of regular values
- Proper nesting and indentation
- Handling objects without BigInts
Good practice to parse the result back to verify structure.
64-93: Comprehensive address validation tests.The tests cover all expected validation scenarios:
- Valid standard addresses
- Valid mixed-case addresses
- Various invalid cases: too short, no prefix, invalid characters, empty
This aligns with the PR's transition to explicit address validation following ENS removal.
src/core/services/transactions.ts (5)
12-12: Default network parameter updated to 'sei'.This change aligns with the PR objective of making the MCP server Sei-specific. The function logic remains the same, only the default network value has changed.
20-20: Default network parameter updated to 'sei'.This change is consistent with the broader refactoring to focus on Sei blockchain support.
28-28: Default network parameter updated to 'sei'.The change aligns with the PR objectives and is applied consistently across transaction-related functions.
37-37: Default network parameter updated to 'sei'.The estimateGas function's default network has been appropriately updated to 'sei'.
45-49: Default network parameter updated to 'sei' with proper type conversion.The getChainId function now defaults to 'sei' network, with appropriate Number() conversion of the chainId from BigInt to number type.
src/tests/core/services/tools.test.ts (3)
12-18: Well-structured test setup.The setup code properly initializes a fresh mock server instance before each test run, ensuring test isolation.
19-37: Comprehensive tool registration verification.Test ensures all expected Sei-specific tools are registered, covering the full range of functionality including:
- Chain information
- Balance operations
- Transfer functionality
- Token operations
- NFT handling
This aligns well with the PR objective of focusing exclusively on Sei.
39-45: Handler verification looks good.This test ensures that each registered tool has a functioning handler implementation, which is important for runtime reliability.
src/tests/core/services/transfer.test.ts (8)
13-22: Clean dependency mocking.The test properly mocks external dependencies to isolate testing of the transfer service. The private key mock aligns with the PR's objective of moving private key handling to environment variables.
23-40: Well-structured mock clients.The mock public and wallet clients provide appropriate stubs for contract interaction and transaction handling. The mock implementations return realistic test values including token details and transaction hashes.
41-49: Good test isolation.The
beforeEachsetup resets all mocks before each test run, ensuring test isolation and consistent behavior across test cases.
51-79: Complete SEI transfer testing.Tests cover both the successful transfer case and the error case when private key is not available. This aligns with the PR's objective of improving private key handling through environment variables.
81-113: Thorough ERC20 transfer testing.The test properly verifies token metadata retrieval and correct transaction formatting. It confirms that the function returns the expected structured result with properly formatted amounts.
115-147: ERC20 approval testing looks good.The test verifies that token approval works correctly and returns the expected format with token details and formatted amounts.
149-178: ERC721 transfer testing is complete.Test verifies NFT metadata retrieval and proper transfer execution, confirming the returned transaction hash and token details.
180-199: ERC1155 transfer testing is implemented correctly.The test confirms proper handling of ERC1155 token transfers with token ID and amount verification.
src/core/prompts.ts (4)
49-64: Well-structured addition of the wallet address promptThe new
my_wallet_addressprompt follows the established pattern and allows users to retrieve their wallet address using the private key stored in environment variables rather than requiring them to provide it directly.
15-17: Parameter descriptions and defaults correctly updated for SeiThe network parameter description and default values have been appropriately updated to reflect the Sei-specific focus of the MCP server.
71-74: Address analysis prompt correctly updated for SeiThe address description has been updated to specifically mention "Sei 0x address" and the default network value has been changed to "sei".
128-140: Network comparison refocused on Sei networksThe network comparison prompt has been appropriately adjusted to focus only on Sei networks, aligning with the PR's objective of making the server Sei-specific.
src/core/services/tokens.ts (3)
82-84: Default network parameter updated to SeiThe default network parameter for the
getERC20TokenInfofunction has been changed from 'ethereum' to 'sei', aligning with the project's focus on the Sei blockchain.
120-122: Default network parameter updated to SeiThe default network parameter for the
getERC721TokenMetadatafunction has been changed from 'ethereum' to 'sei', consistent with other changes across the codebase.
153-155: Default network parameter updated to SeiThe default network parameter for the
getERC1155TokenURIfunction has been changed from 'ethereum' to 'sei', completing the consistent pattern of changes across token-related functions.src/core/services/blocks.ts (4)
10-10: Default network parameter updated to SeiThe default network parameter for
getBlockNumberhas been updated from 'ethereum' to 'sei', consistent with the project's Sei-specific focus.
19-21: Default network parameter updated to SeiThe default network parameter for
getBlockByNumberhas been updated to 'sei', aligning with the other block-related functions and the project's focus on Sei.
30-32: Default network parameter updated to SeiThe default network parameter for
getBlockByHashhas been updated to 'sei', maintaining consistency across the codebase.
40-40: Default network parameter updated to SeiThe default network parameter for
getLatestBlockhas been updated to 'sei', completing the consistent pattern of changes across block-related functions.src/core/services/utils.ts (3)
17-24: Good implementation of address validationThe new
validateAddressfunction provides basic validation for Sei 0x addresses, ensuring they follow the correct format before using them in operations. This is a good security practice to prevent errors from invalid addresses.
1-4: Simplified imports reflect removed utility functionsThe imports have been simplified to only include what's needed after removing several utility functions, which helps maintain a clean codebase.
10-16: Streamlined utility functionsThe utility functions have been streamlined to only include what's needed for the Sei-specific implementation, removing unnecessary formatting and conversion functions.
src/tests/core/services/balance.test.ts (8)
1-20: LGTM! Well-structured test suiteThe test setup is well organized with appropriate use of mocks and test structure. The
afterEachhook ensures proper cleanup between tests.
21-54: Clear and effective testing of getBalanceThe test for
getBalanceproperly mocks dependencies and verifies the function's behavior, ensuring it correctly returns native token balances.
56-96: Well-implemented ERC20 balance testThe test for
getERC20Balancecorrectly mocks contract interactions and verifies the expected metadata is returned along with the balance.
98-120: Comprehensive NFT ownership check testGood test for the positive case of NFT ownership verification.
122-143: Good test coverage for negative NFT ownership caseThe test properly verifies the function returns false when an address does not own the NFT.
145-175: Excellent error handling testThis test ensures the function gracefully handles errors by returning false and properly mocks console.error to keep test output clean. Importantly, it restores the original console.error afterward.
178-200: Effective ERC721 balance testThe test correctly verifies the function's ability to return the number of NFTs owned.
202-226: Solid ERC1155 balance test implementationThe test properly verifies the function's behavior for retrieving ERC1155 token balances.
src/core/services/contracts.ts (6)
9-10: Good refactoring of imports for centralized private key managementThe imports have been updated to use the new centralized private key management system, aligning with the PR objectives.
15-15: Network default updated to SeiThe default network parameter has been updated from 'ethereum' to 'sei', which is consistent with the overall project refocus on Sei blockchain.
20-26: Enhanced documentation with JSDoc commentsThe JSDoc comments have been improved to provide better documentation for parameters, return values, and potential errors.
27-40: Improved private key handling with environment variablesThe function has been refactored to use a centralized private key management approach, removing the private key parameter and retrieving it from environment variables instead. This improves security by avoiding passing private keys directly through function calls.
45-45: Updated getLogs default network to SeiThe default network parameter for the getLogs function has been updated to 'sei', maintaining consistency with the project's new focus.
56-61: ENS support removed and address validation addedThe function has been updated to reflect the removal of ENS support, with direct address validation replacing ENS resolution. This aligns with the PR objective of removing non-working code.
src/core/chains.ts (5)
3-6: Updated chain imports to focus on SeiThe imports have been reduced to only include Sei-related chains, which aligns with the PR objective of making the MCP server specific to Sei.
9-10: Updated default values to Sei mainnetThe default RPC URL and chain ID have been updated to Sei mainnet values, which is consistent with the project refocus.
19-24: Updated network name mappings to Sei chainsThe network name mappings have been updated to focus exclusively on Sei networks, which is consistent with the project's refocus.
72-73: Updated fallback chains to use Sei mainnetThe fallback values in the getChain function have been updated to use Sei mainnet, maintaining consistency with the project's focus on Sei.
Also applies to: 80-80
89-91: Simplified chainId resolution codeThe code has been refactored to a more readable ternary operation, which is a good simplification.
src/core/services/transfer.ts (1)
128-134: Good defensive check for missing private keyThrowing an early, explicit error when
PRIVATE_KEYis absent makes the failure mode clear and prevents silent mis-configuration. Nice touch!
| "url": "https://github.com/sei-protocol/sei-mcp-server/issues" | ||
| }, | ||
| "homepage": "https://github.com/mcpdotdirect/evm-mcp-server#readme", | ||
| "homepage": "https://github.com/sei-protocol/seo-mcp-server#readme", |
There was a problem hiding this comment.
Fix typo in homepage URL.
There appears to be a typo in the homepage URL: "seo-mcp-server" should be "sei-mcp-server".
- "homepage": "https://github.com/sei-protocol/seo-mcp-server#readme",
+ "homepage": "https://github.com/sei-protocol/sei-mcp-server#readme",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "homepage": "https://github.com/sei-protocol/seo-mcp-server#readme", | |
| "homepage": "https://github.com/sei-protocol/sei-mcp-server#readme", |
🤖 Prompt for AI Agents
In package.json at line 73, the homepage URL contains a typo where
"seo-mcp-server" should be corrected to "sei-mcp-server". Update the URL string
to fix this typo so it correctly points to
"https://github.com/sei-protocol/sei-mcp-server#readme".
| "evm-mcp-http": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "@mcpdotdirect/evm-mcp-server", | ||
| "@sei-protocol/sei-mcp-server", | ||
| "--http" | ||
| ] | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Update HTTP server name in mcp.json example
The HTTP server name should also be updated to maintain consistency.
- "evm-mcp-http": {
+ "sei-mcp-http": {
"command": "npx",
"args": [
"-y",
"@sei-protocol/sei-mcp-server",
"--http"
]
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "evm-mcp-http": { | |
| "command": "npx", | |
| "args": [ | |
| "-y", | |
| "@mcpdotdirect/evm-mcp-server", | |
| "@sei-protocol/sei-mcp-server", | |
| "--http" | |
| ] | |
| } | |
| "sei-mcp-http": { | |
| "command": "npx", | |
| "args": [ | |
| "-y", | |
| "@sei-protocol/sei-mcp-server", | |
| "--http" | |
| ] | |
| } |
🤖 Prompt for AI Agents
In README.md around lines 207 to 214, the HTTP server name in the mcp.json
example is outdated. Update the server name to the correct current name to
maintain consistency with the rest of the documentation and configuration
examples.
| # SEI MCP Server | ||
|
|
||
|  | ||
|  | ||
|  | ||
|  | ||
|
|
||
| A comprehensive Model Context Protocol (MCP) server that provides blockchain services across multiple EVM-compatible networks. This server enables AI agents to interact with Ethereum, Optimism, Arbitrum, Base, Polygon, and many other EVM chains with a unified interface. | ||
| Sei Model Context Protocol (Sei MCP) server provides blockchain services for Sei blockchain. | ||
| This server enables AI assistants and agents to interact via unified interface. |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Update project title and description to match Sei focus
The README has been updated to focus on the Sei blockchain, but there are a few inconsistencies in the introduction.
# SEI MCP Server

-
+


Sei Model Context Protocol (Sei MCP) server provides blockchain services for Sei blockchain.
-This server enables AI assistants and agents to interact via unified interface.
+This server enables AI assistants and agents to interact via a unified interface.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # SEI MCP Server | |
|  | |
|  | |
|  | |
|  | |
| A comprehensive Model Context Protocol (MCP) server that provides blockchain services across multiple EVM-compatible networks. This server enables AI agents to interact with Ethereum, Optimism, Arbitrum, Base, Polygon, and many other EVM chains with a unified interface. | |
| Sei Model Context Protocol (Sei MCP) server provides blockchain services for Sei blockchain. | |
| This server enables AI assistants and agents to interact via unified interface. | |
| # SEI MCP Server | |
|  | |
|  | |
|  | |
|  | |
| Sei Model Context Protocol (Sei MCP) server provides blockchain services for Sei blockchain. | |
| This server enables AI assistants and agents to interact via a unified interface. |
🤖 Prompt for AI Agents
In README.md lines 1 to 9, the project title and description should be updated
to clearly reflect the focus on the Sei blockchain. Ensure the title explicitly
mentions "Sei MCP Server" and the description concisely explains that this
server provides blockchain services specifically for the Sei blockchain,
enabling AI assistants and agents to interact through a unified interface.
Adjust wording for clarity and consistency with the Sei blockchain context.
| export const chainMap: Record<number, Chain> = { | ||
| // Mainnets | ||
| 1: mainnet, | ||
| 10: optimism, | ||
| 42161: arbitrum, | ||
| 42170: arbitrumNova, | ||
| 8453: base, | ||
| 137: polygon, | ||
| 1101: polygonZkEvm, | ||
| 43114: avalanche, | ||
| 56: bsc, | ||
| 324: zksync, | ||
| 59144: linea, | ||
| 42220: celo, | ||
| 100: gnosis, | ||
| 250: fantom, | ||
| 314: filecoin, | ||
| 1284: moonbeam, | ||
| 1285: moonriver, | ||
| 25: cronos, | ||
| 534352: scroll, | ||
| 5000: mantle, | ||
| 169: manta, | ||
| 994873017: lumiaMainnet, | ||
| 81457: blast, | ||
| 252: fraxtal, | ||
| 34443: mode, | ||
| 1088: metis, | ||
| 255: kroma, | ||
| 7777777: zora, | ||
| 1313161554: aurora, | ||
| 7700: canto, | ||
| 747: flowMainnet, | ||
|
|
||
| // Testnets | ||
| 11155111: sepolia, | ||
| 11155420: optimismSepolia, | ||
| 421614: arbitrumSepolia, | ||
| 84532: baseSepolia, | ||
| 80002: polygonAmoy, | ||
| 43113: avalancheFuji, | ||
| 97: bscTestnet, | ||
| 300: zksyncSepoliaTestnet, | ||
| 59141: lineaSepolia, | ||
| 1952959480: lumiaTestnet, | ||
| 534351: scrollSepolia, | ||
| 5003: mantleSepoliaTestnet, | ||
| 3441006: mantaSepoliaTestnet, | ||
| 168587773: blastSepolia, | ||
| 2522: fraxtalTestnet, | ||
| 919: modeTestnet, | ||
| 59902: metisSepolia, | ||
| 2358: kromaSepolia, | ||
| 999999999: zoraSepolia, | ||
| 44787: celoAlfajores, | ||
| 5: goerli, | ||
| 17000: holesky, | ||
| 545: flowTestnet, | ||
| 1329: sei, | ||
| 1328: seiTestnet, | ||
| 713_715: seiDevnet | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix underscore in number literal used as object key
The static analysis tool flagged an issue with using underscores in number literals used as object keys.
export const chainMap: Record<number, Chain> = {
- 713_715: seiDevnet
+ 713715: seiDevnet
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const chainMap: Record<number, Chain> = { | |
| // Mainnets | |
| 1: mainnet, | |
| 10: optimism, | |
| 42161: arbitrum, | |
| 42170: arbitrumNova, | |
| 8453: base, | |
| 137: polygon, | |
| 1101: polygonZkEvm, | |
| 43114: avalanche, | |
| 56: bsc, | |
| 324: zksync, | |
| 59144: linea, | |
| 42220: celo, | |
| 100: gnosis, | |
| 250: fantom, | |
| 314: filecoin, | |
| 1284: moonbeam, | |
| 1285: moonriver, | |
| 25: cronos, | |
| 534352: scroll, | |
| 5000: mantle, | |
| 169: manta, | |
| 994873017: lumiaMainnet, | |
| 81457: blast, | |
| 252: fraxtal, | |
| 34443: mode, | |
| 1088: metis, | |
| 255: kroma, | |
| 7777777: zora, | |
| 1313161554: aurora, | |
| 7700: canto, | |
| 747: flowMainnet, | |
| // Testnets | |
| 11155111: sepolia, | |
| 11155420: optimismSepolia, | |
| 421614: arbitrumSepolia, | |
| 84532: baseSepolia, | |
| 80002: polygonAmoy, | |
| 43113: avalancheFuji, | |
| 97: bscTestnet, | |
| 300: zksyncSepoliaTestnet, | |
| 59141: lineaSepolia, | |
| 1952959480: lumiaTestnet, | |
| 534351: scrollSepolia, | |
| 5003: mantleSepoliaTestnet, | |
| 3441006: mantaSepoliaTestnet, | |
| 168587773: blastSepolia, | |
| 2522: fraxtalTestnet, | |
| 919: modeTestnet, | |
| 59902: metisSepolia, | |
| 2358: kromaSepolia, | |
| 999999999: zoraSepolia, | |
| 44787: celoAlfajores, | |
| 5: goerli, | |
| 17000: holesky, | |
| 545: flowTestnet, | |
| 1329: sei, | |
| 1328: seiTestnet, | |
| 713_715: seiDevnet | |
| }; | |
| export const chainMap: Record<number, Chain> = { | |
| 1329: sei, | |
| 1328: seiTestnet, | |
| 713715: seiDevnet | |
| }; |
🧰 Tools
🪛 Biome (1.9.4)
[error] 16-16: Number literal with underscore is not allowed here.
Safe fix: Replace 713_715 with 713715
(lint/complexity/useSimpleNumberKeys)
🤖 Prompt for AI Agents
In src/core/chains.ts between lines 13 and 17, the object key 713_715 uses an
underscore in a number literal, which is not allowed. Replace the key with a
valid number literal without underscores, such as 713715, to fix the static
analysis error.
| // Map chain IDs to RPC URLs | ||
| export const rpcUrlMap: Record<number, string> = { | ||
| // Mainnets | ||
| 1: 'https://eth.llamarpc.com', | ||
| 10: 'https://mainnet.optimism.io', | ||
| 42161: 'https://arb1.arbitrum.io/rpc', | ||
| 42170: 'https://nova.arbitrum.io/rpc', | ||
| 8453: 'https://mainnet.base.org', | ||
| 137: 'https://polygon-rpc.com', | ||
| 1101: 'https://zkevm-rpc.com', | ||
| 43114: 'https://api.avax.network/ext/bc/C/rpc', | ||
| 56: 'https://bsc-dataseed.binance.org', | ||
| 324: 'https://mainnet.era.zksync.io', | ||
| 59144: 'https://rpc.linea.build', | ||
| 42220: 'https://forno.celo.org', | ||
| 100: 'https://rpc.gnosischain.com', | ||
| 250: 'https://rpc.ftm.tools', | ||
| 314: 'https://api.node.glif.io/rpc/v1', | ||
| 1284: 'https://rpc.api.moonbeam.network', | ||
| 1285: 'https://rpc.api.moonriver.moonbeam.network', | ||
| 25: 'https://evm.cronos.org', | ||
| 534352: 'https://rpc.scroll.io', | ||
| 5000: 'https://rpc.mantle.xyz', | ||
| 169: 'https://pacific-rpc.manta.network/http', | ||
| 81457: 'https://rpc.blast.io', | ||
| 252: 'https://rpc.frax.com', | ||
| 994873017: 'https://mainnet-rpc.lumia.org', | ||
| 34443: 'https://mainnet.mode.network', | ||
| 1088: 'https://andromeda.metis.io/?owner=1088', | ||
| 255: 'https://api.kroma.network', | ||
| 7777777: 'https://rpc.zora.energy', | ||
| 1313161554: 'https://mainnet.aurora.dev', | ||
| 7700: 'https://canto.gravitychain.io', | ||
| 747: 'https://mainnet.evm.nodes.onflow.org', | ||
|
|
||
| // Testnets | ||
| 11155111: 'https://sepolia.drpc.org', | ||
| 11155420: 'https://sepolia.optimism.io', | ||
| 421614: 'https://sepolia-rpc.arbitrum.io/rpc', | ||
| 84532: 'https://sepolia.base.org', | ||
| 80002: 'https://rpc-amoy.polygon.technology', | ||
| 43113: 'https://api.avax-test.network/ext/bc/C/rpc', | ||
| 97: 'https://data-seed-prebsc-1-s1.binance.org:8545', | ||
| 300: 'https://sepolia.era.zksync.dev', | ||
| 59141: 'https://rpc.sepolia.linea.build', | ||
| 534351: 'https://sepolia-rpc.scroll.io', | ||
| 5003: 'https://rpc.sepolia.mantle.xyz', | ||
| 3441006: 'https://pacific-rpc.sepolia.manta.network/http', | ||
| 1952959480: 'https://testnet-rpc.lumia.org', | ||
| 168587773: 'https://sepolia.blast.io', | ||
| 2522: 'https://rpc.testnet.frax.com', | ||
| 919: 'https://sepolia.mode.network', | ||
| 59902: 'https://sepolia.metis.io/?owner=59902', | ||
| 2358: 'https://api.sepolia.kroma.network', | ||
| 999999999: 'https://sepolia.rpc.zora.energy', | ||
| 44787: 'https://alfajores-forno.celo-testnet.org', | ||
| 5: 'https://rpc.ankr.com/eth_goerli', | ||
| 17000: 'https://ethereum-holesky.publicnode.com', | ||
| 545: 'https://testnet.evm.nodes.onflow.org', | ||
| 1329: 'https://evm-rpc.sei-apis.com', | ||
| 1328: 'https://evm-rpc-testnet.sei-apis.com', | ||
| 713_715: 'https://evm-rpc-arctic-1.sei-apis.com' | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix underscore in number literal used as object key
Another instance of the underscore issue in object keys.
export const rpcUrlMap: Record<number, string> = {
- 713_715: 'https://evm-rpc-arctic-1.sei-apis.com'
+ 713715: 'https://evm-rpc-arctic-1.sei-apis.com'
};🧰 Tools
🪛 Biome (1.9.4)
[error] 30-30: Number literal with underscore is not allowed here.
Safe fix: Replace 713_715 with 713715
(lint/complexity/useSimpleNumberKeys)
🤖 Prompt for AI Agents
In src/core/chains.ts between lines 26 and 31, the object key 713_715 uses an
underscore in a numeric literal, which is invalid syntax for object keys.
Replace the key with a valid number without underscores, or if it represents a
range or combined value, use a string key instead by enclosing it in quotes.
| export async function getERC721Balance( | ||
| tokenAddressOrEns: string, | ||
| ownerAddressOrEns: string, | ||
| network = 'ethereum' | ||
| tokenAddress: string, | ||
| ownerAddress: string, | ||
| network = 'sei' | ||
| ): Promise<bigint> { | ||
| // Resolve ENS names to addresses if needed | ||
| const tokenAddress = await resolveAddress(tokenAddressOrEns, network); | ||
| const ownerAddress = await resolveAddress(ownerAddressOrEns, network); | ||
|
|
||
| return readContract({ | ||
| address: tokenAddress, | ||
| const validatedTokenAddress = services.helpers.validateAddress(tokenAddress); | ||
| const validatedOwnerAddress = services.helpers.validateAddress(ownerAddress); | ||
|
|
||
| return await readContract({ | ||
| address: validatedTokenAddress, | ||
| abi: erc721Abi, | ||
| functionName: 'balanceOf', | ||
| args: [ownerAddress] | ||
| args: [validatedOwnerAddress] | ||
| }, network) as Promise<bigint>; | ||
| } |
There was a problem hiding this comment.
Incorrect await … as Promise<bigint> causes a type mismatch
Using await resolves the promise to a bigint, but the value is then cast back to Promise<bigint>.
TypeScript will flag this as an error and at runtime the returned value will be a plain bigint, not a Promise.
- return await readContract({
- address: validatedTokenAddress,
- abi: erc721Abi,
- functionName: 'balanceOf',
- args: [validatedOwnerAddress]
- }, network) as Promise<bigint>;
+ return readContract(
+ {
+ address: validatedTokenAddress,
+ abi: erc721Abi,
+ functionName: 'balanceOf',
+ args: [validatedOwnerAddress]
+ },
+ network
+ );Apply the same fix to getERC1155Balance below (lines 204-213).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export async function getERC721Balance( | |
| tokenAddressOrEns: string, | |
| ownerAddressOrEns: string, | |
| network = 'ethereum' | |
| tokenAddress: string, | |
| ownerAddress: string, | |
| network = 'sei' | |
| ): Promise<bigint> { | |
| // Resolve ENS names to addresses if needed | |
| const tokenAddress = await resolveAddress(tokenAddressOrEns, network); | |
| const ownerAddress = await resolveAddress(ownerAddressOrEns, network); | |
| return readContract({ | |
| address: tokenAddress, | |
| const validatedTokenAddress = services.helpers.validateAddress(tokenAddress); | |
| const validatedOwnerAddress = services.helpers.validateAddress(ownerAddress); | |
| return await readContract({ | |
| address: validatedTokenAddress, | |
| abi: erc721Abi, | |
| functionName: 'balanceOf', | |
| args: [ownerAddress] | |
| args: [validatedOwnerAddress] | |
| }, network) as Promise<bigint>; | |
| } | |
| export async function getERC721Balance( | |
| tokenAddress: string, | |
| ownerAddress: string, | |
| network = 'sei' | |
| ): Promise<bigint> { | |
| const validatedTokenAddress = services.helpers.validateAddress(tokenAddress); | |
| const validatedOwnerAddress = services.helpers.validateAddress(ownerAddress); | |
| return readContract( | |
| { | |
| address: validatedTokenAddress, | |
| abi: erc721Abi, | |
| functionName: 'balanceOf', | |
| args: [validatedOwnerAddress] | |
| }, | |
| network | |
| ); | |
| } |
🤖 Prompt for AI Agents
In src/core/services/balance.ts around lines 174 to 188, remove the incorrect
type assertion "as Promise<bigint>" after the awaited call in getERC721Balance,
since awaiting already resolves the promise to a bigint. Instead, just return
the awaited result directly. Apply the same fix to getERC1155Balance in lines
204 to 213 by removing the "as Promise<bigint>" after the await expression.
| const contract = getContract({ | ||
| address: tokenAddress, | ||
| address: tokenAddress as Address, | ||
| abi: erc20TransferAbi, | ||
| client: publicClient, | ||
| }); | ||
|
|
There was a problem hiding this comment.
Unvalidated address used when instantiating the ERC20 contract
validatedTokenAddress is computed but the raw, potentially invalid tokenAddress is passed to getContract.
This defeats the purpose of the address validation step and could lead to runtime errors.
- const contract = getContract({
- address: tokenAddress as Address,
+ const contract = getContract({
+ address: validatedTokenAddress,
abi: erc20TransferAbi,
client: publicClient,
});🤖 Prompt for AI Agents
In src/core/services/transfer.ts between lines 183 and 188, the code uses the
raw tokenAddress instead of the validatedTokenAddress when calling getContract.
To fix this, replace tokenAddress with validatedTokenAddress in the getContract
call to ensure only a validated address is used for the ERC20 contract
instantiation, preventing potential runtime errors.
|
sorry, had to go to a forked repo |
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Refactor
Chores
.gitignorefor environment files.Tests